home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ccdl151s.zip / SOURCE / AN68.C < prev    next >
C/C++ Source or Header  |  1997-06-14  |  10KB  |  277 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include        <stdio.h>
  23. #include        "expr.h"
  24. #include        "c.h"
  25. #include        "gen68.h"
  26. #include                 "diag.h"
  27.  
  28. /* pc-relative expressions not optimized */
  29. extern int linkreg,basereg;
  30. extern AMODE    push[], pop[];
  31. extern OCODE    *peep_tail;
  32. extern SYM *currentfunc;
  33. extern int prm_stackcheck,prm_phiform,prm_linkreg,prm_rel, prm_smalldata;
  34. extern int floatregs,dataregs,addrregs;
  35. extern long framedepth,stackdepth;
  36. extern int cf_maxfloat, cf_maxaddress,cf_maxdata;
  37. extern int cf_freedata,cf_freeaddress;
  38. extern CSE       *olist;         /* list of optimizable expressions */
  39. long lc_maxauto;
  40.  
  41. int save_mask, fsave_mask;
  42. void reserveregs(int *datareg, int *addreg, int *floatreg)
  43. /*
  44.  * Reserve regs goes through and reserves a register for variables with
  45.  * the REGISTER keyword.  Note that it currently does register allocation
  46.  * backwards...
  47.  */
  48. {
  49.     CSE *csp = olist;
  50.  
  51.     while (csp) {
  52.         switch (csp->exp->nodetype) {
  53.                                 case en_floatref:
  54.                                 case en_doubleref:
  55.                                 case en_longdoubleref:
  56.                 case en_b_ref:
  57.                 case en_w_ref:
  58.                 case en_l_ref:
  59.                 case en_ub_ref:
  60.                 case en_uw_ref:
  61.                                 case en_ul_ref:
  62.                                         if (csp->exp->v.p[0]->nodetype != en_autoreg)        
  63.                                             break;
  64.                                           if (csp->exp->nodetype == en_floatref || csp->exp->nodetype == en_doubleref 
  65.                                                 || csp->exp->nodetype == en_longdoubleref) {
  66.                                                 if (*floatreg <cf_maxfloat && floatregs)
  67.                                                     csp->reg = (*floatreg)++;
  68.                                             }
  69.                             else if( (*datareg < cf_maxdata) && (csp->duses <= csp->uses/4) && dataregs)
  70.                         csp->reg = (*datareg)++;
  71.                             else if(!(csp->size == 1 || csp->size == -1) && (*addreg < cf_maxaddress) &&addrregs)
  72.                         csp->reg = (*addreg)++;
  73.                                             if (csp->reg != -1) {
  74.                                                 ((SYM *)csp->exp->v.p[0]->v.p[0])->inreg = TRUE;
  75.                                                 ((SYM *)csp->exp->v.p[0]->v.p[0])->value.i = -csp->reg;
  76.                                             }
  77.                                             break;
  78.         }
  79.         csp = csp->next;
  80.     }
  81. }    
  82.  
  83. void allocate(int datareg, int addreg, int floatreg, SNODE *block )
  84. /*
  85.  *      allocate will allocate registers for the expressions that have
  86.  *      a high enough desirability.
  87.  */
  88. {       CSE      *csp;
  89.         ENODE    *exptr;
  90.         unsigned      mask, rmask,i,fmask,frmask,size;
  91.         AMODE    *ap, *ap2;
  92.                 framedepth = 4+lc_maxauto;
  93.         mask = 0;
  94.                 rmask = 0;
  95.                 fmask = frmask = 0;
  96.                 for (i=cf_freedata; i < datareg; i++) {
  97.                         framedepth+=4;
  98.                         rmask = rmask | (1 << (15 - i));
  99.                         mask = mask | (1 << i);
  100.                 }
  101.                 for (i=cf_freeaddress+16; i < addreg; i++) {
  102.                         framedepth+=4;
  103.                         rmask = rmask | (1 << (23 - i));
  104.                         mask = mask | (1 << (i-8));
  105.                 }
  106.         while( bsort(&olist) );         /* sort the expression list */
  107.         csp = olist;
  108.         while( csp != 0 ) {
  109.                         if (csp->reg == -1 && !(csp->exp->cflags & DF_VOL) && !csp->voidf) {
  110.                 if( desire(csp) < 3 )
  111.                         csp->reg = -1;
  112.                                 else {
  113.                                     if (csp->exp->nodetype == en_rcon || csp->exp->nodetype == en_fcon || csp->exp->nodetype == en_lrcon
  114.                                               || csp->exp->nodetype == en_floatref || csp->exp->nodetype ==en_doubleref
  115.                                                 || csp->exp->nodetype == en_longdoubleref) {
  116.                                         if (floatreg <24 && floatregs)
  117.                                             csp->reg = floatreg++;
  118.                                     }
  119.                         else if( (datareg < cf_maxdata) && (csp->duses <= csp->uses/4) && dataregs)
  120.                     csp->reg = (datareg)++;
  121.                         else if( !(csp->size == 1 || csp->size == -1) && (addreg < cf_maxaddress) &&addrregs)
  122.                       csp->reg = (addreg)++;
  123.                                 }
  124.                         }
  125.             if( csp->reg != -1 )
  126.                 {
  127.                         if (lvalue(csp->exp) && !((SYM *)csp->exp->v.p[0]->v.p[0])->funcparm) {
  128.                             ((SYM *)csp->exp->v.p[0]->v.p[0])->inreg = TRUE;
  129.                             ((SYM *)csp->exp->v.p[0]->v.p[0])->value.i = -csp->reg;
  130.                         }
  131.                         if (csp->reg < 16) {
  132.                             framedepth+=4;
  133.                             rmask = rmask | (1 << (15 - csp->reg));
  134.                         mask = mask | (1 << csp->reg);
  135.                         }
  136.                         else if (csp->reg < 32) {
  137.                             framedepth+=4;
  138.                             rmask = rmask | (1 << (23 - csp->reg));
  139.                         mask = mask | (1 << (csp->reg-8));
  140.                         }
  141.                         else {
  142.                             framedepth+=12;
  143.                             frmask = frmask | (1 << (39 - csp->reg));
  144.               fmask = fmask | (1 << (csp->reg-32));
  145.                         }
  146.                 }
  147.                 csp = csp->next;
  148.                 }
  149.                 allocstack();                                /* Allocate stack space for the local vars */
  150.                 if (currentfunc->tp->lst.head !=0 && currentfunc->tp->lst.head != (SYM *)-1) {
  151.                     if (prm_phiform || currentfunc->intflag) {
  152.                         mask |= (1 << (linkreg +8));
  153.                         rmask |= (1 << (15 - linkreg -8));
  154.                         framedepth+=4;
  155.                     }
  156.                     if (currentfunc->intflag) {
  157.                         mask |= 0xffff;
  158.                         rmask |= 0xffff;
  159.                         framedepth = lc_maxauto;
  160.                     }
  161.                 }
  162.                 if (prm_linkreg && !currentfunc->intflag && (currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *)-1 || lc_maxauto)) {
  163.                     gen_code(op_link,0,makeareg(linkreg),make_immed(-lc_maxauto));
  164.                 }                
  165.               if( mask != 0 ) 
  166.               gen_code(op_movem,4,make_mask(rmask,0,0),push);
  167.         save_mask = mask;
  168.                 if (fmask!=0)
  169.                 gen_code(op_fmovem,10,make_mask(frmask,0,1),push);
  170.                 fsave_mask = fmask;
  171.                 if ((prm_phiform || currentfunc->intflag) && currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *) -1) {
  172.                     gen_code(op_move,4,makeareg(0), makeareg(linkreg));
  173.                 }
  174.                 if ((!prm_linkreg || currentfunc->intflag) && lc_maxauto) {
  175.                     AMODE *ap = xalloc(sizeof(AMODE)); 
  176.                     ap->mode = am_indx;
  177.                     ap->offset = makenode(en_icon,(char *)-lc_maxauto,0);
  178.                     ap->preg = 7;
  179.           gen_code(op_lea,0,ap,makeareg(7));
  180.                 }
  181.                 
  182.                 if (prm_stackcheck) {
  183.                     AMODE *ap1;
  184.                     ap = set_symbol("_stackerror",1);
  185.                     ap1 = set_symbol("_stackbottom",0);
  186.                     if (prm_rel) {
  187.                         ap1->mode = am_indx;
  188.                         ap1->preg = basereg;
  189.                     }
  190.                     else {
  191.                         ap1->mode = am_adirect;
  192.                         if (prm_smalldata)
  193.                             ap1->preg = 2;
  194.                         else
  195.                             ap1->preg = 4;
  196.                     }
  197.                     gen_code(op_cmp,4,ap1,makeareg(7));
  198.                     gen_code(op_bhi,0,ap,0);
  199.                 }
  200. }
  201. void loadregs(void)
  202. /*
  203.  * Initailze allocated regs
  204.  *
  205.  */
  206. {       CSE      *csp;
  207.         ENODE    *exptr;
  208.         unsigned      mask, rmask,i,fmask,frmask,size;
  209.         AMODE    *ap, *ap2;
  210.         csp = olist;
  211.         while( csp != 0 ) {
  212.                                 int sz;
  213.                 if( csp->reg != -1 )
  214.                         {               /* see if preload needed */
  215.                         exptr = csp->exp;
  216.                         if( !lvalue(exptr) || ((SYM *)exptr->v.p[0]->v.p[0])->funcparm )
  217.                                 {
  218.                                                                 exptr = csp->exp;
  219.                                 initstack();
  220.                                                                 sz = csp->size;
  221.                                 ap = gen_expr(exptr,F_ALL,sz);
  222.                                               if (sz == 0 && ap->mode == am_immed)
  223.                                                                     sz = 4;
  224.                                 if( csp->reg < 16 ) {
  225.                                                   if (sz == 0 && ap->mode == am_immed)
  226.                                                                         sz = 4;
  227.                                                                     if (ap->mode == am_dreg)
  228.                                                                         peep_tail->oper2->preg = csp->reg;
  229.                                                                     else {
  230.                                         ap2 = makedreg(csp->reg);
  231.                                                 gen_code(op_move,sz,ap,ap2);
  232.                                                                                 do_extend(ap2,sz,4,F_DREG);
  233.                                                                     }
  234.                                                                 }
  235.                                 else
  236.                                                                     if (csp->reg < 32) {
  237.                                                       if (sz == 0 && ap->mode == am_immed)
  238.                                                                             sz = 4;
  239.                                                                         if (ap->mode == am_areg)
  240.                                                                             peep_tail->oper2->preg = csp->reg - 16;
  241.                                                                         else {
  242.                                             ap2 = makeareg(csp->reg - 16);
  243.                                                     gen_code(op_move,4,ap,ap2);
  244.                                                                         }
  245.                                                                     }
  246.                                                                     else {
  247.                                                       if (sz == 0 && ap->mode == am_immed)
  248.                                                                             sz = 8;
  249.                                                                         if (ap->mode == am_freg)
  250.                                                                             peep_tail->oper2->preg = csp->reg - 32;
  251.                                                                         else {
  252.                                             ap2 = makefreg(csp->reg - 32);
  253.                                                                                     size = 8;
  254.                                                                                     if (exptr->nodetype == en_floatref)
  255.                                                                                         size = 6;
  256.                                                     gen_code(op_fmove,size,ap,ap2);
  257.                                                                         }
  258.                                                                     }
  259.                                 freeop(ap);
  260.                                                                 if (lvalue(exptr) && ((SYM *)exptr->v.p[0]->v.p[0])->funcparm) {
  261.                                                                     ((SYM *)exptr->v.p[0]->v.p[0])->inreg = TRUE;
  262.                                                                     ((SYM *)exptr->v.p[0]->v.p[0])->value.i = -csp->reg;
  263.                                                                 }
  264.                                 }
  265.                         }
  266.                 csp = csp->next;
  267.                 }
  268. }
  269. void voidfloat(SNODE *block)
  270. {
  271. }
  272. void asm_scan(OCODE *cd)
  273. {
  274. }
  275. void asm_repcse(OCODE *cd)
  276. {
  277. }